package app;

import java.util.*;

public class Node {
	private String name;
	private double probability;
	private List<Node> childNodes;

	private List<Node> parentNodes;
	private List<Double> parentProbabilities;
	
	public Node() {
		probability = Double.NaN;
		childNodes = new ArrayList<Node>();
		
		parentNodes = new ArrayList<Node>();
		parentProbabilities = new ArrayList<Double>();
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public void setProbability(double probability) {
		this.probability = probability;
	}

	public double getProbability() {
		if (Double.isNaN(probability))
			computeProbability();
		
		return probability;
	}
	
	public List<Node> getChildNodes() {
		return childNodes;
	}
	
	public void addParentNode(Node parentNode) {
		parentNodes.add(parentNode);
	}
	
	public void addChildNode(Node childNode) {
		childNodes.add(childNode);
	}
	
	public void addParentProbability(double probability) {
		parentProbabilities.add(probability);
	}
	
	public void computeProbability() {
		int probSize = parentProbabilities.size();
		int parentSize = parentNodes.size();
		
		// sanity check
		if (probSize != Math.pow(2, parentSize)) {
			System.out.println("Wrong number of probabilities!");
			System.exit(-1);
		}
		
		probability = 0;
//		System.out.println("Node: " + name);
		for (int i = 0; i < probSize; i++) {
			double combProb = parentProbabilities.get(i);
			int binaryNumber = probSize - 1 - i;
			int position = parentSize - 1;
			
			do {
				boolean binaryValue = (binaryNumber % 2 ) == 1;
				double parentProb = parentNodes.get(position).getProbability(); 
					
				if (binaryValue)
					combProb *= parentProb;
				else
					combProb *= (1 - parentProb);
				
				binaryNumber /= 2;
				position--;
			} while (binaryNumber > 0 || position >= 0 );
			
//			System.out.println("parent probability " + parentProbabilities.get(i) + " value: " + combProb);
			
			probability += combProb;
		}
	}
	
	public String toString() {
		return name;
	}
}
